/*******************************************************************************
 * Copyright (c) 2011 squid.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     squid - initial API and implementation
 ******************************************************************************/
package com.google.code.cubeirc.common;


import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLConnection;

import org.apache.log4j.Level;

import com.google.code.cubeirc.debug.DebuggerQueue;


public class HTTPClient {
	/**
	 * Sends an HTTP GET request to a url
	 *
	 * @param endpoint - The URL of the server. (Example: " http://www.yahoo.com/search")
	 * @param requestParameters - all the request parameters (Example: "param1=val1&param2=val2"). Note: This method will add the question mark (?) to the request - DO NOT add it yourself
	 * @return - The response from the end point
	 */
	public static String sendGetRequest(String endpoint, String requestParameters)
	{
		String result = null;
		if (endpoint.startsWith("http://"))
		{
			try
			{
				// Send data
				System.setProperty("java.net.useSystemProxies", "true");
				String urlStr = endpoint;
				if (requestParameters != null && requestParameters.length () > 0)
				{
					urlStr += "?" + requestParameters;
				}
				URL url = new URL(urlStr);				


				URLConnection conn = url.openConnection ();				
				// Get the response
				BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
				StringBuffer sb = new StringBuffer();
				String line;
				while ((line = rd.readLine()) != null)
				{
					sb.append(line + "\n");
				}
				rd.close();
				result = sb.toString();
			} catch (Exception e)
			{
				DebuggerQueue.addDebug(HTTPClient.class.getName(),Level.ERROR, "Error during download url %s error: %s", endpoint, e.getMessage());
			}
		}
		return result;
	}
	/**
	 * Reads data from the data reader and posts it to a server via POST request.
	 * data - The data you want to send
	 * endpoint - The server's address
	 * output - writes the server's response to output
	 * @throws Exception
	 */
	public static void postData(Reader data, URL endpoint, Writer output) throws Exception
	{
		HttpURLConnection urlc = null;
		try
		{
			urlc = (HttpURLConnection) endpoint.openConnection();
			try
			{
				urlc.setRequestMethod("POST");
			} catch (ProtocolException e)
			{
				throw new Exception("Shouldn't happen: HttpURLConnection doesn't support POST??", e);
			}
			urlc.setDoOutput(true);
			urlc.setDoInput(true);
			urlc.setUseCaches(false);
			urlc.setAllowUserInteraction(false);
			urlc.setRequestProperty("Content-type", "text/xml; charset=" + "UTF-8");
			OutputStream out = urlc.getOutputStream();
			try
			{
				Writer writer = new OutputStreamWriter(out, "UTF-8");
				pipe(data, writer);
				writer.close();
			} catch (IOException e)
			{
				throw new Exception("IOException while posting data", e);
			} finally
			{
				if (out != null)
					out.close();
			}
			InputStream in = urlc.getInputStream();
			try
			{
				Reader reader = new InputStreamReader(in);
				pipe(reader, output);
				reader.close();
			} catch (IOException e)
			{
				throw new Exception("IOException while reading response", e);
			} finally
			{
				if (in != null)
					in.close();
			}
		} catch (IOException e)
		{
			throw new Exception("Connection error (is server running at " + endpoint + " ?): " + e);
		} finally
		{
			if (urlc != null)
				urlc.disconnect();
		}
	}
	/**
	 * Pipes everything from the reader to the writer via a buffer
	 */
	private static void pipe(Reader reader, Writer writer) throws IOException
	{
		char[] buf = new char[1024];
		int read = 0;
		while ((read = reader.read(buf)) >= 0)
		{
			writer.write(buf, 0, read);
		}
		writer.flush();
	}

	public static void downloadFromUrl(URL url, String localFilename, String userAgent)
			throws IOException {
		InputStream is = null;
		FileOutputStream fos = null;
		System.setProperty("java.net.useSystemProxies", "true");

		try {
			URLConnection urlConn = url.openConnection();

			if (userAgent != null) {
				urlConn.setRequestProperty("User-Agent", userAgent);
			}

			is = urlConn.getInputStream();
			fos = new FileOutputStream(localFilename);

			byte[] buffer = new byte[4096];
			int len;

			while ((len = is.read(buffer)) > 0) {
				fos.write(buffer, 0, len);
			}
		} finally {
			try {
				if (is != null) {
					is.close();
				}
			} finally {
				if (fos != null) {
					fos.close();
				}
			}
		}
	}
}


